//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Text;

namespace OpenLS.Spreadsheet.Expressions
{
    internal class ArrayExpression : Expression
    {
        private List<Expression> _currentList;
        private readonly List<List<Expression>> _expressions;

        internal ArrayExpression()
        {
            _currentList = new List<Expression>();
            _expressions = new List<List<Expression>> {_currentList};
        }
        internal ArrayExpression(IEnumerable<IEnumerable<Expression>> values)
        {
            _expressions = new List<List<Expression>>();
            foreach (var line in values)
            {
                var list = new List<Expression>(line);
                Expressions.Add(list);
            }

        }

        internal List<List<Expression>> Expressions
        {
            get { return _expressions; }
        }

        internal override Expression Transposed(Cell target)
        {
            return new ArrayExpression(Enumerable.Select(Expressions, expressions => Enumerable.Select(expressions, expression => expression.Transposed(target))));
        }


        internal void Add(Expression cellExpression)
        {
            _currentList.Add(cellExpression);
        }

        public override IEnumerable<Expression> GetSubExpressions()
        {
            foreach (var l in Expressions)
                foreach (Expression e in l)
                    yield return e;
        }

        private IEnumerable<Expression> getExpressions()
        {
            foreach (var l in Expressions)
                foreach (Expression e in l)
                    yield return e;
        }

        public override string GetText(TextContext context)
        {
            var result = new StringBuilder();
            result.Append("{");
            foreach (var l in Expressions)
                foreach (Expression exp in l)
                {
                    result.Append(exp.GetText(context));
                    if (exp == l[l.Count - 1])
                    {
                        if (l != Expressions[Expressions.Count - 1])
                            result.Append(";"); //\\humm?
                    }
                    else
                        result.Append(context.FormulaArgumentSeparator);
                }

            result.Append("}");
            return result.ToString();
        }

        public override IEnumerable<IDependencyNode> GetPrecedents(EvaluationContext context)
        {
            foreach (Expression e in getExpressions())
                foreach (IDependencyNode cell in e.GetPrecedents(context))
                    yield return cell;
        }

        protected override object GetObjectImp(EvaluationContext context)
        {
            var result = new List<List<object>>();
            foreach (var expl in Expressions)
            {
                var oo = new List<object>();
                foreach (Expression exp in expl)
                {
                    oo.Add(exp.GetObject(context));
                }
                result.Add(oo);
            }
            return new ArrayValue(result);
        }

        public override Expression Offset(CellRelativeAddress a)
        {
            return this;
        }

        internal void AddRow()
        {
            _currentList = new List<Expression>();
            this._expressions.Add(_currentList);
        }
    }
}